package implementaciones;
// import java.magic.*; 
import interfaz.*;
import java.rmi.server.*;
import java.io.*;
import servidor.*;
import java.rmi.RemoteException;
import java.util.*;
import java.text.SimpleDateFormat;

public class interfazServidorImpl extends UnicastRemoteObject implements interfazServidor {

    private conexionRE conexion = new conexionRE();
    private HashSet registrados = new HashSet();
    private HashMap partidoUser = new HashMap();
    private String IP;

    public interfazServidorImpl(String IP) throws RemoteException {
        super();
        this.IP = IP;
    }
    //Este método implementa las operaciones implementadas en interfaz

    public String validarRut(String rut) {
        int Digito;
        int Contador;
        int Multiplo;
        int Acumulador;
        String RutDigito;
        int int_rut = Integer.parseInt(rut);

        Contador = 2;
        Acumulador = 0;

        while (int_rut != 0) {
            Multiplo = (int_rut % 10) * Contador;
            Acumulador = Acumulador + Multiplo;
            int_rut = int_rut / 10;
            Contador = Contador + 1;
            if (Contador == 8) {
                Contador = 2;
            }
        }
        Digito = 11 - (Acumulador % 11);
        RutDigito = Integer.toString(Digito);
        // Digito.ToString().Trim();
        if (Digito == 10) {
            RutDigito = "K";
        }
        if (Digito == 11) {
            RutDigito = "0";
        }
        return RutDigito;
    }

    //Devuelve true si en una cadena que llega todos son numeros, false en caso contrario
    public boolean esEntero(String cad) {
        for (int i = 0; i < cad.length(); i++) {
            if (!Character.isDigit(cad.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public String damePartido(String RUT) throws RemoteException{
        if(verifyPP(RUT)){
             
            String resultado =partidoUser.get(RUT).toString();
            escribirLog("<" + obtenerFecha() + ">" + "<damePartido>" + "<Datos:" + RUT+">"
                                + "<" + resultado+">");
            return resultado;
        
        }
        else{
             String resultado ="Usuario sin partido";
            escribirLog("<" + obtenerFecha() + ">" + "<damePartido>" + "<Datos:" + RUT+">"
                                + "<" + resultado+">");
         
            return resultado;
        }
       
    
    }
    
    @Override
    public String regPP(String RUT, String partido) throws RemoteException {

        //////////////////////////verificación de rut/////////////
        boolean sinCaracteres;
        String[] partes_rut = RUT.split("-");
        String numeros = partes_rut[0];
        sinCaracteres = esEntero(numeros);
        int num_caracteres = partes_rut[0].length();

        //Se verifica que se haya ingresado solo dígitos y el guión
        if ((sinCaracteres == true) && (partes_rut.length != 1)) {
            //Se verifica que el número de dígitos antes del guión correspondan a los de un Rut
            if ((num_caracteres == 7) || (num_caracteres == 8)) {
                String respDV = validarRut(partes_rut[0]);
                String DVer = partes_rut[1];
                //Se verifica que el Rut sea original
                if (respDV.equals(DVer)) {

                    boolean Resultado = false;

                    /*El RUT de la persona no se encuentra en la BD, se agrega entonces.*/

                    try {
                        //Intentamos conectarnos con el servidor de RE
                        //Si hay exito empezamos a consumir servicios
                        if (conexion.iniciarRegistry(IP)) {
                            Resultado = conexion.getServidor().verifyRUT(RUT);

                        }//Fin if de conexion
                    } //fin try de conexion con RE
                    catch (RemoteException ex) {
                        escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                                + "<" + "Error de conexion con RE>");
                        return "Error de conexión con RE";
                    }
                    /*Verifico si el rut se encuentra registrado en en RE*/
                    if (Resultado == true) {

                        if (verifyPP(RUT) != true) {  //Si no está en PP, lo agrego

                            try {
                                BufferedWriter bw = new BufferedWriter(new FileWriter("servPP.txt", true));
                                bw.write("\n" + RUT + "," + partido + "," + obtenerFecha());
                                // Hay que cerrar el fichero
                                bw.close();
                                escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                                        + "<Agregado con exito>");
                                registrados.add(RUT);
                                partidoUser.put(RUT, partido);

                                return "Agregado con exito";
                            } catch (IOException ioe) {
                                //    ioe.printStackTrace();
                                escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                                        + "<Error de apertura de archivo>");
                                return "Error de apertura de archivo";
                            }
                        } else {   //Si ya estaba en PP, no hago nada
                            escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                                    + "<Ya se encuentra registrado en PP>");
                            return "Ya se encuentra registrado en PP";
                        }
                    }
                    //Si no esta en RE, no es posible realizar operacion
                    escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                            + "<No es posible realizar la operacion>");
                    //return numeros;
                    return "No es posible realizar la operación";
                } else {
                    escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                            + "<Rut Inválido. Ingrese un Rut Válido.>");
                    return "Rut Inválido. Ingrese un Rut Válido.";
                }
            } else {
                escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                        + "<El Rut ingresado no posee la cantidad de dígitos de un Rut.>");
                return "El Rut ingresado no posee la cantidad de dígitos de un Rut";
            }
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">"
                    + "<Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.>");
            return "Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.";
        }
    }

    public boolean verifyPP(String RUT) throws RemoteException {

        if (registrados.contains(RUT)) {
            escribirLog("<" + obtenerFecha() + ">" + "<verifyPP>" + "<Datos:" + RUT + ">" + "<true>");
            return true;
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<verifyPP>" + "<Datos:" + RUT + ">" + "<false>");
            return false;
        }
    }

    @Override
    public String verifyPartidoUser(String RUT, String partido) throws RemoteException {

        if (partidoUser.get(RUT).equals((Object) partido)) {
           escribirLog("<" + obtenerFecha() + ">" + "<verifyPartidoUser>" + "<Datos:" + RUT+","+partido+ ">" + "<true>");
          return "0";

        } else {
           escribirLog("<" + obtenerFecha() + ">" + "<verifyPartidoUser>" + "<Datos:" + RUT+","+partido+ ">" + "<false>");
           return "1";
        }
    }

    public String desPP(String RUT) throws RemoteException {
        //////////////////////////verificación de rut/////////////
        boolean sinCaracteres;
        String[] partes_rut = RUT.split("-");
        String numeros = partes_rut[0];
        sinCaracteres = esEntero(numeros);
        int num_caracteres = partes_rut[0].length();

        //Se verifica que se haya ingresado solo dígitos y el guión
        if ((sinCaracteres == true) && (partes_rut.length != 1)) {
            //Se verifica que el número de dígitos antes del guión correspondan a los de un Rut
            if ((num_caracteres == 7) || (num_caracteres == 8)) {
                String respDV = validarRut(partes_rut[0]);
                String DVer = partes_rut[1];
                //Se verifica que el Rut sea original
                if (respDV.equals(DVer)) {
                    File archivo = new File("servPP.txt");
                    FileReader fr = null;
                    BufferedReader br;
                    boolean exito = false;
                    Vector vector = new Vector();

                    //Abro archivo y saco las lineas de texto
                    try {

                        fr = new FileReader(archivo);
                        br = new BufferedReader(fr);

                        // Lectura del fichero linea por linea
                        String linea;
                        String[] contLinea = null;


                        while ((linea = br.readLine()) != null) {

                            contLinea = linea.split(",");  //Guardo el contenido de linea en un arreglo

                            if (contLinea[0].equals(RUT)) {
                                //  return "Borrado con exito";
                                exito = true;
                            } else {
                                vector.addElement(linea);
                            }

                        }//fin ciclo while

                    }//fin try de lectura
                    catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (null != fr) {
                                fr.close();
                            }
                        } catch (Exception e2) {
                            e2.printStackTrace();
                        }
                    }

                    if (exito) {

                        for (int i = 0; i < vector.size(); i++) {
                            try {
                                if (i == 0) {
                                    BufferedWriter bw = new BufferedWriter(new FileWriter("servPP.txt", false));
                                    bw.write("");
                                }
                                BufferedWriter bw = new BufferedWriter(new FileWriter("servPP.txt", true));
                                String linea_nueva = (String) vector.get(i);
                                bw.write(linea_nueva + "\n");
                                // Hay que cerrar el fichero
                                bw.close();
                            } catch (IOException ioe) {
                                //ioe.printStackTrace();
                                escribirLog("<" + obtenerFecha() + ">" + "<desPP>" + "<Datos:" + RUT + ">"
                                        + "<Error de apertura de archivos>");
                                return "Error de apertura de archivos";
                            }
                        }
                        registrados.remove(RUT);
                        escribirLog("<" + obtenerFecha() + ">" + "<desPP>" + "<Datos:" + RUT + ">"
                                + "<Borrado con exito>");
                        return "Borrado con exito";
                    } else {
                        escribirLog("<" + obtenerFecha() + ">" + "<desPP>" + "<Datos:" + RUT + ">"
                                + "<No existe tal rut en sistema>");
                        return "No existe tal rut en sistema";
                    }
                } else {
                    escribirLog("<" + obtenerFecha() + ">" + "<desPP>" + "<Datos:" + RUT + ">"
                            + "<Rut Inválido. Ingrese un Rut Válido.>");
                    return "Rut Inválido. Ingrese un Rut Válido.";
                }
            } else {
                escribirLog("<" + obtenerFecha() + ">" + "<desPP>" + "<Datos:" + RUT + ">"
                        + "<El Rut ingresado no posee la cantidad de dígitos de un Rut.>");
                return "El Rut ingresado no posee la cantidad de dígitos de un Rut";
            }
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<desPP>" + "<Datos:" + RUT + ">"
                    + "<Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.>");
            return "Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.";
        }

    }

    
    public void cargarRegistrados() throws RemoteException {
        File archivo = new File("servPP.txt");
        FileReader fr = null;
        BufferedReader br;
        boolean exito = false;
        Vector vector = new Vector();

        //Abro archivo y saco las lineas de texto
        try {

            fr = new FileReader(archivo);
            br = new BufferedReader(fr);

            // Lectura del fichero linea por linea
            String linea;
            String[] contLinea = null;


            while ((linea = br.readLine()) != null) {

                contLinea = linea.split(",");  //Guardo el contenido de linea en un arreglo
                if(contLinea.length>=2){
                registrados.add(contLinea[0]);
                partidoUser.put(contLinea[0],contLinea[1]);
                }
                }


        }//fin try de lectura
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != fr) {
                    fr.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    public void escribirLog(String mensaje) {

        File archivo;
        archivo = new File("servPP.log");

        try {

            FileWriter w = new FileWriter(archivo, true);
            BufferedWriter bw = new BufferedWriter(w);
            PrintWriter wr = new PrintWriter(bw);

            if (archivo.exists()) {
                wr.append(mensaje + "\n");
            }

            wr.close();
            bw.close();
        } catch (IOException e) {
        }
        ;
    }

    private String obtenerFecha() {

        Date fechaActual = new Date();
        SimpleDateFormat formato = new SimpleDateFormat("dd-MM-yyyy");
        String cadenaFecha = formato.format(fechaActual);

        return cadenaFecha;
    }

    @Override
    public String regRE(String RUT, String nombre, String comuna, String precand) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean verifyRUT(String RUT) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String regREPP(String RUT, String nombre, String comuna, String partido, String precand) throws RemoteException {

        //////////////////////////verificación de rut/////////////
        boolean sinCaracteres;
        String[] partes_rut = RUT.split("-");
        String numeros = partes_rut[0];
        sinCaracteres = esEntero(numeros);
        int num_caracteres = partes_rut[0].length();

        //Se verifica que se haya ingresado solo dígitos y el guión
        if ((sinCaracteres == true) && (partes_rut.length != 1)) {
            //Se verifica que el número de dígitos antes del guión correspondan a los de un Rut
            if ((num_caracteres == 7) || (num_caracteres == 8)) {
                String respDV = validarRut(partes_rut[0]);
                String DVer = partes_rut[1];
                //Se verifica que el Rut sea original
                if (respDV.equals(DVer)) {
                    String Resultado;

                    if (verifyPP(RUT)) {
                        escribirLog("<" + obtenerFecha() + ">" + "<regREPP>" + "<Datos:" + RUT + "," + nombre + "," + comuna + ","
                                + partido + "," + precand + ">" + "<Ya se encuentra registrado este RUT>");
                        return "Ya se encuentra registrado este RUT";

                    } else {

                        try {
                            //Intentamos conectarnos con el servidor de RE
                            //Si hay exito empezamos a consumir servicios
                            if (conexion.iniciarRegistry(IP)) {
                                Resultado = conexion.getServidor().regREPP(RUT, nombre, comuna, partido, precand);
                                regPP(RUT, partido);
                                escribirLog("<" + obtenerFecha() + ">" + "<regREPP>" + "<Datos:" + RUT + "," + nombre + "," + comuna + ","
                                        + partido + "," + precand + ">" + "<" + "Agregado con exito" + ">");
                                return "Agregado con exito";
                            }//Fin if de conexion
                        } //fin try de conexion con RE
                        catch (RemoteException ex) {
                            escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">" + "<" + "Error de conexion con RE>");
                            return "Error de conexión con RE";
                        }
                    }
                    return "caso raro";
                } else {
                    escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">" + "<"
                            + "Rut Inválido. Ingrese un Rut Válido>");
                    return "Rut Inválido. Ingrese un Rut Válido.";
                }
            } else {
                escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">" + "<"
                        + "El Rut ingresado no posee la cantidad de dígitos de un Rut>");
                return "El Rut ingresado no posee la cantidad de dígitos de un Rut";
            }
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<regPP>" + "<Datos:" + RUT + "," + partido + ">" + "<"
                    + "Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado>");
            return "Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.";
        }
    }

    @Override
    public String cargarPrecandidatos(String comuna, String partido) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String votarPrimario(String agregado, String RUT, String comuna, String partido) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
